﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace GDI_应用案例.Pages.Controls._3D
{
    [StructLayout(LayoutKind.Explicit)]
    public unsafe struct Point3D
    {
        public static Point3D Empty;
        [FieldOffset(0)]
        public float X;
        [FieldOffset(4)]
        public float Y;
        [FieldOffset(8)]
        public float Z;
        public Point3D(float x, float y, float z)
        {
            X = x;
            Y = y;
            Z = z;
        }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public PointF ToPointF(float distance)
        {
            float scale = Scale(distance);
            return new PointF(this.X * scale, this.Y * scale);
        }
        /// <summary>
        /// 转2D
        /// </summary>
        /// <param name="p">当前2D坐标</param>
        /// <param name="distance">视点到投影平面的距离</param>
        /// <param name="viewpointPosition">视点位置</param>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public void ToPointF(PointF* p, float distance, Point3D* viewpointPosition)
        {
            float scale = distance / (distance + this.Z+ viewpointPosition->Z);
            p->X = this.X * scale + viewpointPosition->X;
            p->Y = this.Y * scale + viewpointPosition->Y;
        }
        /// <summary>
        /// 透视投影的缩放因子
        /// </summary>
        /// <param name="distance">视点到投影平面的距离</param>
        /// <returns></returns>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        private float Scale(float distance) => distance / (distance + this.Z);
    }
}
